package com.wyx.easyExcel.easyExcelWrite;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.wyx.easyExcel.easyExcelHandler.WeeklySupplyStrategyDataHandler;
import com.wyx.easyExcel.easyExcelHandler.WeeklySupplyStrategyDataHeightHandler;
import com.wyx.easyExcel.easyExcelHandler.WeeklySupplyStrategyDataMerge;
import com.wyx.easyExcel.easyExcelPojo.*;
import com.wyx.easyExcel.easyExcelPojo.putTactics.*;
import com.wyx.pojo.Smoke;
import com.wyx.pojo.constant.Constant;
import com.wyx.pojo.templateConfig.SmokeAnticipatedOrder;
import com.wyx.utils.commonUtil.ExcelUtil;
import com.wyx.utils.commonUtil.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;

import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 吴宇~
 * @motto 我亦无他，唯手熟尔。
 * @edition jdk1.8
 * @reflection 0-1 喧闹任其喧闹，自由我自为之，我自风情万种，与世无争。
 * @date 2024/10/27/11:31
 * @target 心若有所向往，何惧道阻且长
 */
//TODO: 将这部分搞出来一部分做一个 单独的服务。传递足够多的参数，表示这是一个什么类型， 一个写的参数，一个读的 参数。
//  这个该怎么弄呢？ excel 服务的这个部分，这个服务中要做的事情，到底是什么，主要的一个问题，是否需要在这个服务内查询数据库，
//  关于处理数据的部分，是处理好数据传过来还是，在这个服务里面处理。关于数据库数据的处理，反正数据过来也要查询，索性在那儿查号就得了。

// 删除的部分 略有瑕疵，索引分不清了。
@Slf4j
public class WeeklySupplyStrategyDataTempleWrite {

    /**
     * @param inputStream              模板文件
     * @param excelTypeEnum            excel文件类型
     * @param weeklySupplyStrategyData 基本数据
     * @return 返回对应的文件图片
     */
    public static byte[] process(InputStream inputStream,
                                 ExcelTypeEnum excelTypeEnum,
                                 WeeklySupplyStrategyData weeklySupplyStrategyData,
                                 Map<String, Smoke> dbInfo,
                                 SmokeAnticipatedOrder smokeAnticipatedOrder) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        List<AnticipatedRelease> gearPutList = new ArrayList<>();
        List<AnticipatedRelease> pricePutList = new ArrayList<>();
        List<AnticipatedRelease> gearExtendPutList = new ArrayList<>();

        // 获取档位投放数据
        for (AnticipatedOrderData anticipatedOrderData : weeklySupplyStrategyData.getGearSelection().getList()) {
            AnticipatedRelease anticipatedRelease = anticipatedOrderDataToAnticipatedRelease(dbInfo, anticipatedOrderData);
            gearPutList.add(anticipatedRelease);
        }

        // 将档位投放数据进行排序
        sort(gearPutList);

        // 获取价格投放数据
        for (PriceSelection selection : weeklySupplyStrategyData.getPriceSelection()) {
            List<AnticipatedOrderData> list = selection.getList();
            for (AnticipatedOrderData anticipatedOrderData : list) {
                AnticipatedRelease anticipatedRelease = anticipatedOrderDataToAnticipatedRelease(dbInfo, anticipatedOrderData);
                pricePutList.add(anticipatedRelease);
            }
            //  通过这个对象代替，对应的限制数量
            AnticipatedRelease anticipatedRelease = listToAnticipatedRelease(selection.getGearPutUpperLimit());
            anticipatedRelease.setName("价位段订购上限");
            pricePutList.add(anticipatedRelease);
        }

        // 为了可以合并单元格 在前面多加一行
        gearExtendPutList.add(new AnticipatedRelease(null));
        //  获取档位扩展投放方式 的 数据
        for (GearExtendSelection gearExtendSelection : weeklySupplyStrategyData.getGearExtendSelectionList()) {
            List<AnticipatedOrderData> list = gearExtendSelection.getList();
            for (int i = 0; i < list.size(); i++) {
                AnticipatedRelease anticipatedRelease = anticipatedOrderDataToAnticipatedRelease(dbInfo, list.get(i));
                if (i != 0) {
                    anticipatedRelease.setName(null);
                    anticipatedRelease.setWholePrice(null);
                    anticipatedRelease.setAlloType(null);
                }
                gearExtendPutList.add(anticipatedRelease);
            }
        }

        // 得到单纯实际订购的有效数据，根据农网和城网得出来的。
        List<AnticipatedRelease> allValidData = getAllValidData(weeklySupplyStrategyData, dbInfo, gearPutList);

        // 根据上面的所有信息得到下面的统计信息
        List<PutStatistics> putStatisticsList = getPutStatistics(allValidData);

        // 得到每个档位的订购信息 档位是通过配置得到的。
        int[] orderDetailGearS = smokeAnticipatedOrder.getOrderDetailGearS();
        // 得到订单每个档位的详细数据
        List<OrderDetail> orderDetails = getOrderDetailList(allValidData, putStatisticsList, orderDetailGearS);
        Map<String, Integer> baseHeightMap = getBaseHeight(
                gearPutList,
                pricePutList,
                gearExtendPutList,
                orderDetails,
                smokeAnticipatedOrder);
        Integer gearPutBaseHeight = baseHeightMap.get("gearPutBaseHeight");
        Integer pricePutBaseHeight = baseHeightMap.get("pricePutBaseHeight");
        Integer gearExtendPutBaseHeight = baseHeightMap.get("gearExtendPutBaseHeight");
        Integer orderDetailBaseHeight = baseHeightMap.get("orderDetailBaseHeight");
        Integer remarkBaseHeight = baseHeightMap.get("remarkBaseHeight");

        // 得到订单详情的每一行的行高
        List<RowObj> heightList = getOrderDetailListHeight(orderDetails, orderDetailBaseHeight);
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setWrapped(true);
        ExcelWriter excelWriterBuild = EasyExcel
                .write(byteArrayOutputStream)
                .withTemplate(inputStream)
                .excelType(excelTypeEnum)
                .registerWriteHandler(new WeeklySupplyStrategyDataHandler(getStyleMap(gearPutList, smokeAnticipatedOrder), 3))
                .registerWriteHandler(new WeeklySupplyStrategyDataMerge(
                        getMergeData(gearPutList,
                                pricePutList,
                                gearExtendPutList,
                                smokeAnticipatedOrder,
                                orderDetails,
                                gearPutBaseHeight,
                                pricePutBaseHeight,
                                gearExtendPutBaseHeight,
                                orderDetailBaseHeight,
                                remarkBaseHeight)))
                .registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, headWriteCellStyle))
                .registerWriteHandler(new WeeklySupplyStrategyDataHeightHandler(heightList))
                .build();

        FillConfig fillConfig_VERTICAL = FillConfig.builder().direction(WriteDirectionEnum.VERTICAL).forceNewRow(Boolean.TRUE).build();
        FillConfig fillConfig_HORIZONTAL = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
        WriteSheet build = EasyExcel.writerSheet().build();
        excelWriterBuild.fill(new FillWrapper("gear", gearPutList), fillConfig_VERTICAL, build);
        excelWriterBuild.fill(new FillWrapper("price", pricePutList), fillConfig_VERTICAL, build);
        excelWriterBuild.fill(new FillWrapper("gearExtend", gearExtendPutList), fillConfig_VERTICAL, build);
        excelWriterBuild.fill(new FillWrapper("statistics", putStatisticsList), fillConfig_HORIZONTAL, build);
        excelWriterBuild.fill(new FillWrapper("orderDetail", orderDetails), fillConfig_VERTICAL, build);
        excelWriterBuild.fill(getMap(weeklySupplyStrategyData, smokeAnticipatedOrder), build);
        excelWriterBuild.finish();
        // 美化excel 二次读取excel。做一些easyExcel 不太方便做的事情
        List<Integer> deleteLine = new ArrayList<>();
        deleteLine.add(gearExtendPutBaseHeight + 1);
        deleteLine.add(orderDetailBaseHeight+1);
        ByteArrayOutputStream beautificationRes = beautification(deleteLine, null, byteArrayOutputStream.toByteArray());
        return beautificationRes.toByteArray();
    }

    /**
     * 美化处理单元格，主要解决easyExcel 不太好解决的问题
     *
     * @param deleteIndexList 删除的行 从0开始数
     * @param rowObjs         设置指定行为指定的高度
     * @param bytes           数据
     * @return 返回处理后的数据
     */
    private static ByteArrayOutputStream beautification(List<Integer> deleteIndexList, List<RowObj> rowObjs, byte[] bytes) {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Workbook workbook = null;
        try {
            workbook = new HSSFWorkbook(byteArrayInputStream);
            Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
            // 设置指定行的行高
            for (Integer integer : deleteIndexList) {
                Row row = sheet.getRow(integer - 1);
                if (row != null) {
                    row.setHeightInPoints(0);
                }
            }
            if (rowObjs != null) {
                for (RowObj rowObj : rowObjs) {
                    Row row = sheet.getRow(rowObj.getRowIndex() - 1);
                    if (row != null) {
                        row.setHeightInPoints(rowObj.getRowHeight());
                    }
                }
            }
            // 保存修改后的Excel文件
            try {
                workbook.write(byteArrayOutputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            workbook.close();
            byteArrayOutputStream.close();
        } catch (IOException e) {
            log.error("delete fail ,{}", e.getMessage());
        }
        return byteArrayOutputStream;
    }

    private static Map<String, Integer> getBaseHeight(List<AnticipatedRelease> gearList,
                                                      List<AnticipatedRelease> pricePutList,
                                                      List<AnticipatedRelease> gearExtendPutList,
                                                      List<OrderDetail> orderDetails,
                                                      SmokeAnticipatedOrder smokeAnticipatedOrder) {
        HashMap<String, Integer> baseHeightMap = new HashMap<>();
        int[] listIntervalS = smokeAnticipatedOrder.getListIntervalS();
        int gearSize = gearList.size();
        int pricePutSize = pricePutList.size();
        pricePutSize = pricePutSize != 0 ? pricePutSize : 1;
        int gearExtendPutSize = gearExtendPutList.size();
        int gearPutBaseHeight = listIntervalS[0];
        int pricePutBaseHeight = gearSize + gearPutBaseHeight + listIntervalS[1];
        int gearExtendPutBaseHeight = pricePutSize + pricePutBaseHeight + listIntervalS[2];
        // 后面有这个+1 是加在了档位扩展里面，因为为了调整样式所以添加了一行，不过后来删除了。这儿是不是不 应该呢？因为这个1 设置在了size 里面 TODO： 看样式吧，越看越不顺眼
        int orderDetailBaseHeight = gearExtendPutSize + gearExtendPutBaseHeight + listIntervalS[3];
        int orderDetailSize = orderDetails.size();
        int remarkBaseHeight = orderDetailBaseHeight + orderDetailSize + listIntervalS[4];

        baseHeightMap.put("gearPutBaseHeight", gearPutBaseHeight);
        baseHeightMap.put("pricePutBaseHeight", pricePutBaseHeight);
        baseHeightMap.put("gearExtendPutBaseHeight", gearExtendPutBaseHeight);
        baseHeightMap.put("orderDetailBaseHeight", orderDetailBaseHeight);
        baseHeightMap.put("remarkBaseHeight", remarkBaseHeight);
        return baseHeightMap;
    }

    /**
     * 得到订购详情的行高
     *
     * @param orderDetails 订购详情
     * @return 订单详情行信息
     */
    private static List<RowObj> getOrderDetailListHeight(List<OrderDetail> orderDetails, Integer orderDetailBaseHeight) {
        List<RowObj> rowObjs = new ArrayList<>();
        for (int i = 0; i < orderDetails.size(); i++) {
            OrderDetail orderDetail = orderDetails.get(i);
            if (orderDetail.getGear() != null && orderDetail.getDetailStr() != null) {
                String detailStr = orderDetail.getDetailStr();
                int height = ((detailStr.length() / 133) + 1) * 500;
                RowObj rowObj = new RowObj();
                rowObj.setRowIndex(orderDetailBaseHeight + i + 1);
                rowObj.setRowHeight((short) height);
                rowObjs.add(rowObj);
            }
        }
        return rowObjs;
    }

    /**
     * 根据所有可订购的数据将某些档位的具体订购通过字符串的形式输出
     *
     * @param allValidData      所有有效的数据
     * @param putStatisticsList 档位统计信息
     * @param gears             显示档位
     * @return 返回档位细节对象
     */
    private static List<OrderDetail> getOrderDetailList(List<AnticipatedRelease> allValidData, List<PutStatistics> putStatisticsList, int[] gears) {
        List<OrderDetail> orderDetails = new ArrayList<>();
        orderDetails.add(new OrderDetail());
        for (int j = 0; j < gears.length; j++) {
            int gearLv = gears[j];
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setGear(Constant.AREA_TYPE_VILLAGE + " " + gearLv + " 档");
            StringBuilder orderStrDetail = new StringBuilder();
            for (AnticipatedRelease anticipatedRelease : allValidData) {
                String gearValue = anticipatedRelease.getGearValue(gearLv);
                if (!gearValue.equals("0")) {
                    String smokeName = anticipatedRelease.getName();
                    orderStrDetail.append(StringUtils.replaceParenthesis(smokeName)).append("*[").append(gearValue).append("]").append(",");
                }
            }
            PutStatistics putStatistics = putStatisticsList.get(30 - gearLv);
            orderDetail.setAllotypeNum(putStatistics.getAllotypePutNum() + "");
            orderDetail.setGeneralNum(putStatistics.getGeneralPutNum() + "");
            orderDetail.setOrderAmount(putStatistics.getAmount());
            orderDetail.setTotal(putStatistics.getTotalPutNum() + "");
            orderStrDetail.append("常规:").append(orderDetail.getGeneralNum()).append(",").
                    append("异型:").append(orderDetail.getAllotypeNum()).append(",").
                    append("共计:").append(orderDetail.getTotal()).append(",").
                    append("订单金额:").append(orderDetail.getOrderAmount()).append(".");
            orderDetail.setDetailStr(orderStrDetail.toString());
            orderDetails.add(orderDetail);
        }
        return orderDetails;
    }

    /**
     * 获取样式map
     *
     * @param gearList              档位数据集合
     * @param smokeAnticipatedOrder bean对象
     * @return 返回一个样式map
     */
    private static Map<PointXY, CellStyleWY> getStyleMap(List<AnticipatedRelease> gearList, SmokeAnticipatedOrder smokeAnticipatedOrder) {
        HashMap<PointXY, CellStyleWY> pointXYCellStyleWYHashMap = new HashMap<>();
        for (int i = 0; i < gearList.size(); i++) {
            int totalColumn = 30 + Integer.parseInt(smokeAnticipatedOrder.getPreGearLvColumnNum());
            for (int x = 0; x < totalColumn; x++) {
                PointXY pointXY = new PointXY(x, i + 3);
                CellStyleWY cellStyleWY = new CellStyleWY();
                cellStyleWY.setCellType('0');
                ExcelUtil.fillCellColor(cellStyleWY, i, smokeAnticipatedOrder.getLineColorS());
                int currentGearLv = totalColumn - x;
                short enhanceColor = Short.parseShort(smokeAnticipatedOrder.getEnhanceColor());
                for (int enhanceColorGearLv : smokeAnticipatedOrder.getEnhanceColorGearLvS()) {
                    if (enhanceColorGearLv == currentGearLv) {
                        cellStyleWY.setColorIndex(enhanceColor);
                        break;
                    }
                }
                pointXYCellStyleWYHashMap.put(pointXY, cellStyleWY);
            }
        }
        return pointXYCellStyleWYHashMap;
    }

    /**
     * 获取需要合并单元格的数据
     *
     * @param gearList              档位投放的list
     * @param pricePutList          价格投放的list
     * @param gearExtendPutList     档位扩展投放的list
     * @param smokeAnticipatedOrder 基本的bean信息
     * @return 返回需要合并的单元格的数据
     */
    private static Map<PointXY, MergeBean> getMergeData(List<AnticipatedRelease> gearList,
                                                        List<AnticipatedRelease> pricePutList,
                                                        List<AnticipatedRelease> gearExtendPutList,
                                                        SmokeAnticipatedOrder smokeAnticipatedOrder,
                                                        List<OrderDetail> gearOrderDetails,
                                                        Integer gearPutBaseHeight,
                                                        Integer pricePutBaseHeight,
                                                        Integer gearExtendPutBaseHeight,
                                                        Integer orderDetailBaseHeight,
                                                        Integer remarkBaseHeight) {

        Map<PointXY, MergeBean> pointXYMergeBeanHashMap = new HashMap<>();
        CellStyleWY commonBorderStyle = new CellStyleWY();
        commonBorderStyle.setDownBorderStyle(BorderStyle.THIN);
        // 档位投放的合并区间
        for (int i = 0; i < gearList.size(); i++) {
            PointXY pointXYStart = new PointXY(1, gearPutBaseHeight + i);
            PointXY pointXYEnd = new PointXY(2, gearPutBaseHeight + i);
            MergeBean mergeBean = new MergeBean();
            mergeBean.setStart(pointXYStart);
            mergeBean.setEnd(pointXYEnd);
            mergeBean.setStyleWY(commonBorderStyle);
            pointXYMergeBeanHashMap.put(pointXYStart, mergeBean);
        }
        CellStyleWY priceRangeOrderingLimit = new CellStyleWY();
        priceRangeOrderingLimit.setDownBorderStyle(BorderStyle.THIN);
        // 价格自选投放的合并区间
        for (int i = 0; i < pricePutList.size(); i++) {
            AnticipatedRelease anticipatedRelease = pricePutList.get(i);
            PointXY pointXYStart;
            PointXY pointXYEnd;
            if (anticipatedRelease.getName().equals("价位段订购上限")) {
                pointXYStart = new PointXY(0, pricePutBaseHeight + i);
                pointXYEnd = new PointXY(Integer.parseInt(smokeAnticipatedOrder.getPreGearLvColumnNum()) - 1, pricePutBaseHeight + i);
                priceRangeOrderingLimit.setHorizontalAlignment(HorizontalAlignment.RIGHT);
            } else {
                pointXYStart = new PointXY(1, pricePutBaseHeight + i);
                pointXYEnd = new PointXY(2, pricePutBaseHeight + i);
            }
            MergeBean mergeBean = new MergeBean();
            mergeBean.setStart(pointXYStart);
            mergeBean.setEnd(pointXYEnd);
            mergeBean.setStyleWY(commonBorderStyle);
            pointXYMergeBeanHashMap.put(pointXYStart, mergeBean);
        }
        CellStyleWY gearExtendPutMergeStyle = new CellStyleWY();
        gearExtendPutMergeStyle.setLeftBorderStyle(BorderStyle.THIN);
        gearExtendPutMergeStyle.setRightBorderStyle(BorderStyle.THIN);
        // 档位扩展投放的合并区间
        for (int i = 1; i < gearExtendPutList.size(); ) {
            int[] mergeColumn = {0, 1, 3};
            for (int index : mergeColumn) {
                PointXY pointXYStartName = new PointXY(index, gearExtendPutBaseHeight + i);
                PointXY pointXYEndName = new PointXY(index, gearExtendPutBaseHeight + i + 1);
                MergeBean mergeBeanName = new MergeBean();
                mergeBeanName.setStart(pointXYStartName);
                mergeBeanName.setEnd(pointXYEndName);
                mergeBeanName.setStyleWY(gearExtendPutMergeStyle);
                pointXYMergeBeanHashMap.put(pointXYStartName, mergeBeanName); // 批发价
            }
            i = i + 2;
        }
        CellStyleWY orderDetailCellStyleWY = new CellStyleWY();
        orderDetailCellStyleWY.setDownBorderStyle(BorderStyle.THIN);
        orderDetailCellStyleWY.setRightBorderStyle(BorderStyle.THICK);
        // 订单详情的合并位置
        for (int i = 0; i < gearOrderDetails.size(); i++) {
            PointXY pointXYStart = new PointXY(1, orderDetailBaseHeight + i);
            PointXY pointXYEnd = new PointXY(33, orderDetailBaseHeight + i);

            MergeBean mergeBeanName = new MergeBean();
            mergeBeanName.setStart(pointXYStart);
            mergeBeanName.setEnd(pointXYEnd);
            mergeBeanName.setStyleWY(orderDetailCellStyleWY);
            pointXYMergeBeanHashMap.put(pointXYStart, mergeBeanName);
        }
        // 注意事项的合并区间
        PointXY pointXYStart = new PointXY(1, remarkBaseHeight + 1);
        PointXY pointXYEnd = new PointXY(33, remarkBaseHeight + 1);
        MergeBean mergeBeanName = new MergeBean();
        mergeBeanName.setStart(pointXYStart);
        mergeBeanName.setEnd(pointXYEnd);
        mergeBeanName.setStyleWY(orderDetailCellStyleWY);
        pointXYMergeBeanHashMap.put(pointXYStart, mergeBeanName);
        return pointXYMergeBeanHashMap;
    }

    /**
     * 根据所有有效的数据
     *
     * @param allValidData 所有订购的有效数据
     * @return 返回统计数据
     */
    private static List<PutStatistics> getPutStatistics(List<AnticipatedRelease> allValidData) {
        List<PutStatistics> putStatisticsList = new ArrayList<>();
        for (int i = 0; i < BaseGearInfo.levelNum; i++) {
            PutStatistics putStatistics = new PutStatistics();
            int generalPutNum = 0;
            int allotypePutNum = 0;
            BigDecimal amount = new BigDecimal("0");

            for (AnticipatedRelease data : allValidData) {
                int quantity = Integer.parseInt(data.getGearValue(30 - i));
                boolean isAllotype = Constant.CHAR_TRUE.equals(data.getAlloType());
                boolean isCity = Constant.AREA_TYPE_CITY.equals(data.getCityOrVillage());
                if (data.getCityOrVillage() == null || isCity) {
                    if (isAllotype) {
                        allotypePutNum += quantity;
                    } else {
                        generalPutNum += quantity;
                    }
                }
                if (quantity != 0) {
                    String wholeSalePrice = parseWholePrice(data.getWholePrice());
                    amount = amount.add(new BigDecimal(quantity).multiply(new BigDecimal(wholeSalePrice)));
                }
            }

            int totalPutNum = generalPutNum + allotypePutNum;
            putStatistics.setGeneralPutNum(generalPutNum);
            putStatistics.setAllotypePutNum(allotypePutNum);
            putStatistics.setTotalPutNum(totalPutNum);
            putStatistics.setAmount(amount.setScale(0, RoundingMode.UP).toString());
            putStatisticsList.add(putStatistics);
        }
        return putStatisticsList;
    }


    /**
     * 得到所有的有效数据，指的是已经区分了农网和城网，单独把有效的数据罗列出来
     *
     * @param weeklySupplyStrategyData 传入的基本数据
     * @param dbInfo                   数据库数据
     * @param gearPutList              档位投放数据
     * @return 返回有效的数据清单，这个数据用于后续的计算。
     * <p>
     * 需要传入的是城网还是农网
     */
    private static List<AnticipatedRelease> getAllValidData(WeeklySupplyStrategyData weeklySupplyStrategyData,
                                                            Map<String, Smoke> dbInfo,
                                                            List<AnticipatedRelease> gearPutList) {
        // 档位投放处理
        List<AnticipatedRelease> validAnticipatedReleases = new ArrayList<>(gearPutList);
        // 档位扩展投放
        for (GearExtendSelection gearExtendSelection : weeklySupplyStrategyData.getGearExtendSelectionList()) {
            for (AnticipatedOrderData anticipatedOrderData : gearExtendSelection.getList()) {
                AnticipatedRelease select = anticipatedOrderDataToAnticipatedRelease(dbInfo, anticipatedOrderData);
                if (select.getCityOrVillage().equals("农网")) {
                    validAnticipatedReleases.add(select);
                }
            }
        }
        // 价格自选投放，最后的结果是一个每个档位，每种卷烟，在当前价格区间 `选择` 哪几个
        List<PriceSelection> priceSelectionList = weeklySupplyStrategyData.getPriceSelection();
        for (PriceSelection priceSelection : priceSelectionList) {
            List<AnticipatedOrderData> list = priceSelection.getList();
            // 将数据格式转换一下
            List<AnticipatedRelease> convertResult = list.stream()
                    .map(anticipatedOrderData -> anticipatedOrderDataToAnticipatedRelease(dbInfo, anticipatedOrderData))
                    .collect(Collectors.toCollection(ArrayList::new));

            sort(convertResult);
            for (int gear_index = 0; gear_index < 30; gear_index++) {
                // 当前档位当前选择集订购上限
                Integer currentGearSelectUpperLimit = priceSelection.getGearPutUpperLimit().get(gear_index);
                if (currentGearSelectUpperLimit <= 0) {
                    continue;
                }
                // 实际订购，也可以算是当前订购的一种计算。记录的一个中间变量计算结果
                int actualOrder = 0;
                for (int i = 0; i < convertResult.size(); i++) {
                    AnticipatedRelease anticipatedRelease = convertResult.get(i);
                    // 当前价格段选择，当前档位，当前卷烟订购上限
                    int currentGearSelectCurrentSmokeUpperLimit = Integer.parseInt(anticipatedRelease.getGearValue(30 - gear_index));
                    if (actualOrder <= currentGearSelectUpperLimit && actualOrder + currentGearSelectCurrentSmokeUpperLimit > currentGearSelectUpperLimit) {
                        anticipatedRelease.setGearValue(30 - gear_index, currentGearSelectUpperLimit - actualOrder + "");
                        int i1 = i + 1;
                        if (i1 <= i) {
                            for (int j = i1; j < convertResult.size(); j++) {
                                AnticipatedRelease anticipatedRelease1 = convertResult.get(j);
                                anticipatedRelease1.setGearValue(30 - gear_index, "0");
                            }
                        }
                        break;
                    } else if (actualOrder + currentGearSelectCurrentSmokeUpperLimit == currentGearSelectUpperLimit) {
                        int i1 = i + 1;
                        if (i1 <= i) {
                            for (int j = i1; j < convertResult.size(); j++) {
                                AnticipatedRelease anticipatedRelease1 = convertResult.get(j);
                                anticipatedRelease1.setGearValue(30 - gear_index, "0");
                            }
                        }
                        break;
                    } else if (actualOrder + currentGearSelectCurrentSmokeUpperLimit < currentGearSelectUpperLimit) {
                        actualOrder += currentGearSelectCurrentSmokeUpperLimit;
                    }
                }
            }

            validAnticipatedReleases.addAll(convertResult);
        }
        return validAnticipatedReleases;
    }

    private static AnticipatedRelease anticipatedOrderDataToAnticipatedRelease(Map<String, Smoke> dbInfo, AnticipatedOrderData anticipatedOrderData) {
        AnticipatedRelease anticipatedRelease = new AnticipatedRelease();
        anticipatedRelease.setName(anticipatedOrderData.getProductName());
        anticipatedRelease.setProductCode(anticipatedOrderData.getProductEncoding());
        if (dbInfo.get(anticipatedOrderData.getProductEncoding()) == null) {
            anticipatedRelease.setWholePrice(getNewPrice(anticipatedOrderData.getPriceBand()));
            log.warn("{} 批发价缺失", anticipatedRelease.getName());
        } else {
            anticipatedRelease.setWholePrice(dbInfo.get(anticipatedOrderData.getProductEncoding()).getWholeSalePrice());
        }
        anticipatedRelease.setCityOrVillage(anticipatedOrderData.getType());
        anticipatedRelease.setAlloType(anticipatedOrderData.getAbnormal());
        anticipatedRelease.setPriceBand(anticipatedOrderData.getPriceBand());
        anticipatedRelease.copyLevel(anticipatedOrderData);
        return anticipatedRelease;
    }

    // 将集合转换城 一个对象。对应  AnticipatedRelease 对象
    private static AnticipatedRelease listToAnticipatedRelease(List<Integer> list) {
        AnticipatedRelease anticipatedRelease = new AnticipatedRelease();
        String[] lvs = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            lvs[i] = String.valueOf(list.get(i));
        }
        anticipatedRelease.setData(lvs);
        return anticipatedRelease;
    }

    // 将档位投放合计写入 map
    private static Map<String, String> getMap(WeeklySupplyStrategyData weeklySupplyStrategyData, SmokeAnticipatedOrder smokeAnticipatedOrder) {
        Map<String, String> maps = new HashMap<>();
        List<Integer> gearPutUpperLimit = weeklySupplyStrategyData.getGearSelection().getGearPutUpperLimit();
        maps.put("dateRange", weeklySupplyStrategyData.getNoteInformationMap().get("dateRange"));
        for (int i = 0; i < gearPutUpperLimit.size(); i++) {
            maps.put("gearTotalPut_" + (30 - i), gearPutUpperLimit.get(i).toString());
        }
        StringBuilder remarkStr = new StringBuilder();
        List<String> remarkList = smokeAnticipatedOrder.getRemarkList();
        for (int i = 0; i < remarkList.size(); i++) {
            remarkStr.append(remarkList.get(i)).append("\n");
        }
        maps.put("remark", remarkStr.toString());
        return maps;
    }

    // 排序的方式，本来按照价格排序就好了，但是因为有的价格没有，所以就需要复杂一点。。
    private static void sort(List<AnticipatedRelease> gearPutList) {
        gearPutList.sort((o1, o2) -> {
            int i1 = (int) Double.parseDouble(parseWholePrice(o1.getWholePrice()));
            int i2 = (int) Double.parseDouble(parseWholePrice(o2.getWholePrice()));
            return i1 - i2;
        });
    }

    /**
     * 得到新的价格
     *
     * @param priceStr 价格字符串
     * @return 处理原本的价格字符串得到一个新的价格字符串
     */
    private static String getNewPrice(String priceStr) {
        // 处理 "800元(含)以上" 类型的字符串、
        if (priceStr.contains("以上")) {
            String processedString = priceStr.replace("元", "").replace("(", "").replace(")", "").replace("含", "");
            String[] parts = processedString.split("以上");
            if (parts.length > 0) {
                try {
                    int threshold = Integer.parseInt(parts[0].trim());
                    return "[>" + threshold + "]";
                } catch (NumberFormatException e) {
                    return priceStr;
                }
            }
        }
        // 处理 "[600-800元)" 类型的字符串
        else if (priceStr.startsWith("[") || priceStr.endsWith(")")) {
            String processedString = priceStr.replace("元", "");
            String[] parts = processedString.substring(1, processedString.length() - 1).split("-");
            if (parts.length == 2) {
                try {
                    int lowerBound = Integer.parseInt(parts[0].trim());
                    int upperBound = Integer.parseInt(parts[1].trim());
                    return "[" + lowerBound + "-" + upperBound + ")";
                } catch (NumberFormatException e) {
                    return priceStr;
                }
            }
        }
        return priceStr;
    }

    /**
     * 解析字符串，将 [600-800) 这种字符串，解析成600  800元(含)以上 这种字符串解析成800
     *
     * @param priceStr 显示的价格字符串
     * @return 解析这个字符串，得到一个新的价格，用于计算或者排序
     */
    private static String parseWholePrice(String priceStr) {
        if (priceStr.contains(">") || priceStr.contains("<")) {
            String replace = priceStr.replace(">", "").replace("<", "").replace("[", "").replace("]", "");
            return Integer.parseInt(replace) + "";
        } else if (priceStr.startsWith("[") && priceStr.endsWith(")")) {
            // 处理 "[600-800)" 类型的字符串
            String[] parts = priceStr.substring(1, priceStr.indexOf(")")).split("-");
            if (parts.length == 2) {
                return Integer.parseInt(parts[0].trim()) + "";
            }
        } else if (priceStr.matches("-?\\d+(\\.\\d+)?")) {
            return Double.parseDouble(priceStr) + "";
        }
        throw new IllegalArgumentException("Invalid price range string format: " + priceStr);
    }
}